﻿
using System;


namespace CS.Scheduling
{
    /// <summary>
    /// 任务调度相关的配置接口。
    /// 对Job的配置，如果确信对Job的配置完全正确可以不用。
    /// <para>Provides the fluent API to configure a given <see cref="Job"/>.</para>
    /// </summary>
    public class JobSchedule
    {
        private readonly Job _job;

        /// <summary>
        /// 默认构造，挂接任务用以对该任务进行运行条件的配置。
        /// <para>Creates the instance object with the job to be/ configured.</para>
        /// </summary>
        public JobSchedule(Job job)
        {
            _job = job;
        }
        
        /// <summary>
        /// 设定任务的开始运行时间。
        /// <para>Sets the job's starting time.</para>
        /// </summary>
        /// <param name="startTime">The first execution of the job.</param>
        public JobSchedule From(DateTimeOffset startTime)
        {
            _job.StartTime = startTime;
            return this;
        }

        /// <summary>
        /// 配置任务成仅运行一次。Node:好像不起作用呀
        /// <para>Configures the job to run only once.</para>
        /// </summary>
        public JobSchedule Once()
        {
            _job.Loops = 1;
            _job.ExpirationTime = null;
            _job.Interval = null;
            return this;
        }
        
        /// <summary>
        /// 配置任务运行的间隔时间。
        /// <para>Defines an interval for periodic execution of the  job. The interval needs to be set if the job is  supposed to run more than once.</para>
        /// </summary>
        /// <param name="jobInterval">The job's planned interval.</param>
        internal JobSchedule EveryInternal(TimeSpan jobInterval)
        {
            _job.Interval = jobInterval;
            return this;
        }

        /// <summary>
        /// 分别配置任务运行的间隔时间。
        /// <para>Defines an interval for periodic execution of the job. The interval needs to be set if the job is supposed to run more than once.</para>
        /// </summary>
        public Intervals Every
        {
            get { return new Intervals(this); }
        }

        /// <summary>
        /// 配置任务运行的次数。
        /// <para>Configures the job to run a fixed number of times.</para>
        /// </summary>
        /// <param name="loops">The number of times the job is supposed to run.</param>
        public JobSchedule Times(int loops)
        {
            _job.Loops = loops;
            return this;
        }
        
        /// <summary>
        /// 任务过期时间，即任务的结束时间。
        /// <para>Specifies an <see cref="Job.ExpirationTime"/> for the job. Not required it the job runs only a number of times, or is supposed to run indefinitely with the specified <see cref="Job.Interval"/>.</para>
        /// </summary>
        /// <param name="jobExpirationTime">The specified expiration time.</param>
        public JobSchedule Until(DateTimeOffset jobExpirationTime)
        {
            _job.ExpirationTime = jobExpirationTime;
            return this;
        }
    }


    /// <summary>
    /// 时间间隔结构。
    /// <para>Helper struct that simplifies interval configuration.</para>
    /// </summary>
    public struct Intervals
    {
        private readonly JobSchedule _schedule;

        /// <summary>
        /// 默认构造，将时间间隔与任务调度关联。
        /// <para>Initializes a new instance of the <see cref="T:System.Object"/> class.</para>
        /// </summary>
        public Intervals(JobSchedule schedule)
        {
            _schedule = schedule;
        }

        /// <summary>
        /// 设置间隔时间的毫秒。
        /// <para>Sets an interval of a given number of milliseconds.</para>
        /// </summary>
        /// <param name="value">The interval in milliseconds.</param>
        public JobSchedule Milliseconds(long value)
        {
            return _schedule.EveryInternal(System.TimeSpan.FromMilliseconds(value));
        }

        /// <summary>
        /// 设置间隔时间的秒。
        /// <para>Sets an interval of a given number of seconds.</para>
        /// </summary>
        /// <param name="value">The interval in seconds.</param>
        public JobSchedule Seconds(double value)
        {
            return _schedule.EveryInternal(System.TimeSpan.FromSeconds(value));
        }

        /// <summary>
        /// 设置间隔时间的分钟。
        /// <para>Sets an interval of a given number of minutes.</para>
        /// </summary>
        /// <param name="value">The interval in minutes.</param>
        public JobSchedule Minutes(double value)
        {
            return _schedule.EveryInternal(System.TimeSpan.FromMinutes(value));
        }

        /// <summary>
        /// 设置间隔时间的小时。
        /// </summary>
        /// <param name="value">小时</param>
        /// <returns></returns>
        public JobSchedule Hours(double value)
        {
            return _schedule.EveryInternal(System.TimeSpan.FromHours(value));
        }
        
        /// <summary>
        /// 设置间隔时间的天。
        /// <para>Sets an interval of a given number of days.</para>
        /// </summary>
        /// <param name="value">The interval in days.</param>
        public JobSchedule Days(double value)
        {
            return _schedule.EveryInternal(System.TimeSpan.FromDays(value));
        }

        /// <summary>
        /// 直接以时间间隔设置。
        /// <para>Sets an interval of a given time span.</para>
        /// </summary>
        /// <param name="value">The interval.</param>
        public JobSchedule TimeSpan(TimeSpan value)
        {
            return _schedule.EveryInternal(value);
        }
        
    }


}
